package com.leo.foodmaster.admin.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.leo.foodmaster.admin.system.entity.SysUser;
import com.leo.foodmaster.admin.system.entity.User;
import com.leo.foodmaster.admin.system.entity.UserRole;
import com.leo.foodmaster.admin.system.service.IUserRoleService;
import com.leo.foodmaster.admin.system.service.IUserService;
import com.leo.foodmaster.commons.constants.AuthConstants;
import com.leo.foodmaster.commons.constants.Constants;
import com.leo.foodmaster.commons.exception.AuthenticationFailedException;
import com.leo.foodmaster.commons.util.IpUtils;
import com.leo.foodmaster.commons.util.ServletUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户登录验证/用户权限查询
 * </p>
 *
 * @author ：Leo
 * @since ：2021-06-17 15:57
 */
@Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
    @Resource
    private IUserService userService;
    @Resource
    private IUserRoleService userRoleService;
    @Resource
    private ISysLoginLogServiceImpl sysLoginLogServiceImpl;
    private static final String USER_DISABLED = "1";

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {
        if (StrUtil.isBlank(account)) {
            throw new AuthenticationFailedException("账户名不能为空！");
        }

        // 根据用户名查询用户信息
        SysUser sysUser = userService.getOne(Wrappers.lambdaQuery(SysUser.class)
                .eq(SysUser::getAccount, account));
        if (BeanUtil.isEmpty(sysUser)) {
            String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
            sysLoginLogServiceImpl.asyncSaveLoginLog(ipAddr, account, Constants.LOGIN_FAIL, "登录用户：" + account + " 不存在");
            throw new AuthenticationFailedException("登录用户：" + account + " 不存在");
        }
        if (sysUser.getDelFlag()) {
            String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
            sysLoginLogServiceImpl.asyncSaveLoginLog(ipAddr, account, Constants.LOGIN_FAIL, "账号：" + account + " 已被删除");
            throw new AuthenticationFailedException("对不起，您的账号：" + account + " 已被删除");
        }
        if (USER_DISABLED.equals(sysUser.getStatus())) {
            String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
            sysLoginLogServiceImpl.asyncSaveLoginLog(ipAddr, account, Constants.LOGIN_FAIL, "账号：" + account + " 已停用");
            throw new AuthenticationFailedException("对不起，您的账号：" + account + " 已停用");
        }

        // 根据用户id查询该用户对应的角色
        List<UserRole> userRoles = userRoleService
                .list(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getUserId, sysUser.getId()));
        List<SimpleGrantedAuthority> collect = new ArrayList<>();
        if (!userRoles.isEmpty()) {
            collect = userRoles.stream().map(userRole ->
                    new SimpleGrantedAuthority(AuthConstants.ROLE + userRole.getRoleId().toString()))
                    .collect(Collectors.toList());
        }

        User user = new User();
        BeanUtil.copyProperties(sysUser, user);
        user.setAuthorities(collect);
        return user;
    }
}
